package asava.trees;

import java.util.List;

/**
 * @author Tim Richter
 */
public class TreeVisitor {
    public void visit(final Unit tree) {
        accept(tree.imports);
        tree.declaration.accept(this);
    }

    public void visit(final Import tree) {
        tree.selector.accept(this);
    }

    public void visit(final Class tree) {
        tree.base.accept(this);
        accept(tree.interfaces);
        accept(tree.fields);
        accept(tree.methods);
    }

    public void visit(final Function tree) {
        accept(tree.params);
        tree.result.accept(this);
        tree.body.accept(this);
    }

    public void visit(final Var tree) {
        tree.type.accept(this);
        tree.init.accept(this);
    }

    public void visit(final Empty tree) {
    }

    protected void accept(final List<Tree> trees) {
        for (final Tree tree : trees) {
            tree.accept(this);
        }
    }

    public void visit(final Block tree) {
        accept(tree.trees);
    }

    public void visit(final While tree) {
        tree.condition.accept(this);
        tree.body.accept(this);
    }

    public void visit(final DoWhile tree) {
        tree.condition.accept(this);
        tree.body.accept(this);
    }

    public void visit(final For tree) {
        tree.init.accept(this);
        tree.condition.accept(this);
        tree.step.accept(this);
    }

    public void visit(final ForEach tree) {
        tree.var.accept(this);
        tree.expr.accept(this);
        tree.body.accept(this);
    }

    public void visit(final ForIn tree) {
        tree.var.accept(this);
        tree.expr.accept(this);
        tree.body.accept(this);
    }

    public void visit(final Switch tree) {
        tree.selector.accept(this);
        accept(tree.cases);
    }

    public void visit(final Case tree) {
        tree.key.accept(this);
        tree.body.accept(this);
    }

    public void visit(final Try tree) {
        tree.body.accept(this);
        accept(tree.catches);
        tree.finalizer.accept(this);
    }

    public void visit(final Catch tree) {
        tree.var.accept(this);
        tree.body.accept(this);
    }

    public void visit(final Throw tree) {
        tree.expr.accept(this);
    }

    public void visit(final Return tree) {
        tree.expr.accept(this);
    }

    public void visit(final Labeled tree) {
        tree.body.accept(this);
    }

    public void visit(final Break tree) {
    }

    public void visit(final Continue tree) {
    }

    public void visit(final If tree) {
        tree.condition.accept(this);
        tree.thenPart.accept(this);
        tree.elsePart.accept(this);
    }

    public void visit(final Delete tree) {
        tree.expr.accept(this);
    }

    public void visit(final This tree) {
    }

    public void visit(final Super tree) {
    }

    public void visit(final Ident tree) {
    }

    public void visit(final Select tree) {
        tree.selector.accept(this);
    }

    public void visit(final Apply tree) {
        tree.selector.accept(this);
        accept(tree.args);
    }

    public void visit(final NewClass tree) {
        tree.type.accept(this);
    }

    public void visit(final Assign tree) {
        tree.lhs.accept(this);
        tree.rhs.accept(this);
    }

    public void visit(final BinOp tree) {
        tree.lhs.accept(this);
        tree.rhs.accept(this);
    }

    public void visit(final Conditional tree) {
        tree.condition.accept(this);
        tree.thenPart.accept(this);
        tree.elsePart.accept(this);
    }

    public void visit(final Indexed tree) {
        tree.selector.accept(this);
        tree.index.accept(this);
    }

    public void visit(final Literal tree) {
    }

    public void visit(final Cast tree) {
        tree.type.accept(this);
        tree.expr.accept(this);
    }

    public void visit(final PrefixOp tree) {
        tree.expr.accept(this);
    }

    public void visit(final PostfixOp tree) {
        tree.expr.accept(this);
    }

    public void visit(final TypeRef tree) {
    }

    public void visit(final Parens tree) {
        tree.expr.accept(this);
    }

    public void visit(final NewArray tree) {
        accept(tree.args);
    }
}
